#include "limit.h"
#include "MkLog.h"
#include <regex>
#include <map>
#ifndef _WIN32
#include <regex.h>
#endif
typedef struct _gb_white_item
{
	MkString Describe;
	MkString strWhite;
#ifndef _WIN32
	regex_t reg;
#endif
}GbWhiteItem;

typedef std::map<MkString, GbWhiteItem>	MapGbWhiteList;

Uint32 g_dev_access_count = 0;
MapGbWhiteList	g_WhiteList;

Uint32 gb_add_white_id(const MkString& WhiteId, const MkString& strWhite, const MkString& Describe)
{
	GbWhiteItem Item;
	Item.Describe = Describe;
	Item.strWhite = strWhite;
#ifndef _WIN32
	int flag = REG_EXTENDED;
	regcomp(&Item.reg, strWhite.c_str(), flag);
#endif
	g_WhiteList[WhiteId] = Item;
	return NoneError;
}

Uint32 gb_change_white_id(const MkString& WhiteId, const MkString& strWhite, const MkString& Describe)
{
	MapGbWhiteList::iterator it = g_WhiteList.find(WhiteId);
	if (it != g_WhiteList.end())
	{
		it->second.Describe = Describe;
		it->second.strWhite = strWhite;
	}
	return NoneError;
}

Uint32 gb_delete_white_id(const MkString& WhiteId)
{
	MapGbWhiteList::iterator it = g_WhiteList.find(WhiteId);
	if (it != g_WhiteList.end())
	{
		g_WhiteList.erase(it);
	}
	return NoneError;
}

Uint32 gb_set_device_access_count(Uint32 nCount)
{
	g_dev_access_count = nCount;
	return NoneError;
}

Uint32 GetDevAccessCount()
{
	return g_dev_access_count;
}

BOOL CheckDevAllow(const MkString& DevId)
{
	MapGbWhiteList::iterator it = g_WhiteList.begin();
	for (; it != g_WhiteList.end(); it++)
	{
#ifdef _WIN32
		if (1 == std::regex_match(DevId, std::regex(it->second.strWhite)))
		{
			return TRUE;
		}
#else
		regmatch_t pmatch[1];
		const size_t nmatch = 1;
		int status = regexec(&it->second.reg, DevId.c_str(), nmatch, pmatch, 0);
		if (0 == status)
		{
			MkDebugLog("match succ devid:%s", DevId.c_str());
			return TRUE;
		}
#endif
		MkWarningLog("not math white:%s  devid:%s\n", it->second.strWhite.c_str(), DevId.c_str());
	}
	MkDebugLog("not match dev:%s\n", DevId.c_str());
	return FALSE;
}